package com.xqh.config;

import com.xqh.commom.security.CustomCredentialsMatcher;
import com.xqh.commom.security.FormAuthenticationFilter;
import com.xqh.commom.security.SystemAuthorizingRealm;
import com.xqh.commom.security.session.JedisCacheManager;
import com.xqh.commom.security.session.JedisSessionDAO;
import com.xqh.commom.security.session.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.env.Environment;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    @Bean
    public JedisCacheManager shiroCacheManager(){
        JedisCacheManager cacheManager = new JedisCacheManager();
        cacheManager.setCacheKeyPrefix("ques:admin:shiro:cache");
        return cacheManager;
    }

    @Bean
    public JedisSessionDAO sessionDAO(){
        JedisSessionDAO jedisSessionDAO = new JedisSessionDAO();
        jedisSessionDAO.setSessionKeyPrefix("ques:admin:shiro:cache");
        return jedisSessionDAO;
    }

    @Bean
    public SimpleCookie sessionIdCookie(){
        SimpleCookie cookie = new SimpleCookie("ques.admin.session.id");
        return cookie;
    }

    @Bean
    public CustomCredentialsMatcher credentialsMatcher(){
        return new CustomCredentialsMatcher();
    }

    @Bean
    public SystemAuthorizingRealm systemAuthorizingRealm(){
        SystemAuthorizingRealm realm = new SystemAuthorizingRealm();
        realm.setCredentialsMatcher(credentialsMatcher());
        realm.setAuthenticationCacheName("");
        return realm;
    }

    @Bean
    public SessionManager sessionManager(){
        SessionManager manager = new SessionManager();
        manager.setSessionDAO(sessionDAO());
        manager.setGlobalSessionTimeout(1800000L);
        manager.setSessionValidationSchedulerEnabled(false);
        manager.setSessionIdCookie(sessionIdCookie());
        manager.setSessionIdCookieEnabled(true);
        return manager;
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(systemAuthorizingRealm());
        securityManager.setSessionManager(sessionManager());
        securityManager.setCacheManager(shiroCacheManager());
        return securityManager;
    }

    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        autoProxyCreator.setProxyTargetClass(true);
        return autoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager());
        return advisor;
    }

    @Bean
    public FormAuthenticationFilter formAuthenticationFilter(){
        return new FormAuthenticationFilter();
    }


    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(){
        ShiroFilterFactoryBean sfb = new ShiroFilterFactoryBean();
        sfb.setSecurityManager(securityManager());
        sfb.setLoginUrl("/login");
        sfb.setSuccessUrl("/index");
        sfb.setUnauthorizedUrl("/unauthorized");
        Map<String, Filter> filters=new HashMap<>();
        filters.put("authc",formAuthenticationFilter());
        sfb.setFilters(filters);
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/static/**","anon");
        filterMap.put("/login","authc");
        filterMap.put("/logout","logout");
        filterMap.put("/**","user");
        sfb.setFilterChainDefinitionMap(filterMap);
        return sfb;
    }
}
